package com.zxm.redis;

import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

import org.apache.ibatis.cache.Cache;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.util.SerializationUtils;

import redis.clients.jedis.JedisCluster;

public class RedisMybatisCache implements Cache{

	private String id;
	
	private static final ReadWriteLock lock = new ReentrantReadWriteLock();
	
	private static final JedisCluster jedisCluster = getJedisCluser();
	
	//todo 如何使用@Value(使用的前提是什么？？？)
	private static final String jedisKey="jedisKey";
	
	
	public RedisMybatisCache(String id) {
		super();
		this.id = id;
	}

	@Override
	public String getId() {
		return this.id;
	}
	/**
	 * 获得JedisCluser
	 */
	public static JedisCluster getJedisCluser() {
		//读取配置文件
		ApplicationContext context = new ClassPathXmlApplicationContext("spring-common.xml","spring-redis.xml");
		JedisCluster jedisCluster = context.getBean("jedisCluster", redis.clients.jedis.JedisCluster.class);
		
		return jedisCluster;
	}
	/**
	 * 向缓存中添加数据  Jedis的数据类型使用hash
	 * key：本质为sql语句
	 * value：从数据库中执行sql查询出的结果
	 */
	@Override
	public void putObject(Object key, Object value) {
		System.out.println("-----put-----");
		//使用hash保存数据
		System.out.println(key);
		jedisCluster.hset(SerializationUtils.serialize(jedisKey),SerializationUtils.serialize(key),SerializationUtils.serialize(value));
	}

	/**
	 * 从sql中获取数据
	 * key:本质为sql语句
	 */
	@Override
	public Object getObject(Object key) {
		System.out.println("-----get--------");
		System.out.println(key);
		byte[] res = jedisCluster.hget(SerializationUtils.serialize(jedisKey), SerializationUtils.serialize(key));
		if(res!=null && res.length>0) {
			return SerializationUtils.deserialize(res);
		}
		return null;
	}

	/**
	 * 从缓存中删除数据
	 * key：本质为sql语句
	 */
	@Override
	public Object removeObject(Object key) {
		return jedisCluster.hdel(SerializationUtils.serialize(jedisKey), SerializationUtils.serialize(key));
	}

	/**
	 * 清空缓存中所有的数据
	 */
	@Override
	public void clear() {
		jedisCluster.del(SerializationUtils.serialize(jedisKey));
	}

	/**
	 * 获取缓存的条数
	 */
	@Override
	public int getSize() {
		return jedisCluster.hlen(SerializationUtils.serialize(jedisKey)).intValue();
	}

	/**
	 * 读写锁，与synch功能相同
	 * 让多线程保证线程安全，需要是同一个锁，所以锁要声明为全局的
	 */
	@Override
	public ReadWriteLock getReadWriteLock() {
		return lock;
	}

}
